package com.hitqz.robot.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hitqz.robot.admin.api.dto.UserDTO;
import com.hitqz.robot.admin.api.entity.*;
import com.hitqz.robot.admin.api.service.SysDictItemService;
import com.hitqz.robot.admin.api.service.SysDictService;
import com.hitqz.robot.admin.api.vo.UserExcelVO;
import com.hitqz.robot.api.business.entity.CvdQuestionAnswerEntity;
import com.hitqz.robot.api.business.dto.CvdQuestionAnswerQueryDTO;
import com.hitqz.robot.api.business.dto.CvdQuestionAnswerSaveDTO;
import com.hitqz.robot.api.business.dto.CvdQuestionAnswerUpdateDTO;
import com.hitqz.robot.api.business.entity.CvdVoiceEntity;
import com.hitqz.robot.api.business.vo.CvdQuestionAnswerExcelVO;
import com.hitqz.robot.api.business.vo.CvdQuestionAnswerVO;
import com.hitqz.robot.biz.mapper.CvdQuestionAnswerMapper;
import com.hitqz.robot.biz.service.CvdQuestionAnswerService;
import com.hitqz.robot.common.core.exception.ErrorCodes;
import com.hitqz.robot.common.core.util.MsgUtils;
import com.hitqz.robot.common.core.util.R;
import com.hitqz.robot.common.file.core.FileProperties;
import com.pig4cloud.plugin.excel.vo.ErrorMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.BindingResult;

import java.io.File;
import java.net.URL;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 语音交互问答库
 *
 * @author kehanjiang
 * @date 2025-09-25 10:33:40
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CvdQuestionAnswerServiceImpl extends ServiceImpl<CvdQuestionAnswerMapper, CvdQuestionAnswerEntity> implements CvdQuestionAnswerService {
    private final SysDictService sysDictService;
    private final SysDictItemService sysDictItemService;

    private final static String SYS_INNER_TYPE = "系统内置";

    private CvdQuestionAnswerVO convertToVO(Object o) {
        if (o instanceof CvdQuestionAnswerEntity) {
            CvdQuestionAnswerVO vo = new CvdQuestionAnswerVO();
            BeanUtil.copyProperties(o, vo);
            //设置其他参数
            String label = vo.getLabel();
            if (StrUtil.isNotBlank(label)) {
                String[] labels = label.split(",");
                vo.setLabelList(List.of(labels));
            }
            return vo;
        }
        return null;
    }

    private void preCheck(CvdQuestionAnswerEntity entity, Boolean update) {
        Long id = entity.getId();
        //String name = entity.getName();
        if (update) {//更新操作
            Assert.notNull(id, "id不可为空！");
        } else {
            //Assert.hasText(name, "name不可为空！");
        }
    }

    @Override
    public Page<CvdQuestionAnswerVO> getCvdQuestionAnswerPage(Page page, CvdQuestionAnswerQueryDTO dto) {
        CvdQuestionAnswerEntity entity = new CvdQuestionAnswerEntity();
        BeanUtils.copyProperties(dto, entity);
        entity.setLabel(null);
        entity.setAnswerContent(null);
        final String label = dto.getLabel();
        final String answerContent = dto.getAnswerContent();
        LambdaQueryWrapper<CvdQuestionAnswerEntity> wrapper = new LambdaQueryWrapper<>(entity);
        wrapper.like(StringUtils.hasText(label), CvdQuestionAnswerEntity::getLabel, label);
        wrapper.like(StringUtils.hasText(answerContent), CvdQuestionAnswerEntity::getAnswerContent, answerContent);
        wrapper.orderByDesc(CvdQuestionAnswerEntity::getId);
        return (Page<CvdQuestionAnswerVO>) this.page(page, wrapper)
                .convert(this::convertToVO);
    }

    @Override
    public CvdQuestionAnswerVO getCvdQuestionAnswerById(Long id) {
        Assert.notNull(id, "id不可为空！");
        return convertToVO(this.getById(id));
    }


    @Override
    public Boolean saveCvdQuestionAnswer(CvdQuestionAnswerSaveDTO dto) {
        CvdQuestionAnswerEntity entity = new CvdQuestionAnswerEntity();
        BeanUtils.copyProperties(dto, entity);
        this.preCheck(entity, false);
        List<String> labelList = Optional.ofNullable(dto.getLabelList()).orElse(new ArrayList<>());
        if (CollUtil.isNotEmpty(labelList)) {
            entity.setLabel(labelList.stream().map(label -> label.trim()).collect(Collectors.joining(",")));
        }
        return this.save(entity);
    }

    @Override
    public Boolean updateCvdQuestionAnswerById(CvdQuestionAnswerUpdateDTO dto) {
        CvdQuestionAnswerEntity entity = new CvdQuestionAnswerEntity();
        BeanUtils.copyProperties(dto, entity);
        this.preCheck(entity, true);
        CvdQuestionAnswerEntity oldEntity = this.getById(entity.getId());
        String oldContent = oldEntity.getAnswerContent();
        String newContent = entity.getAnswerContent();
        if (!oldContent.equals(newContent)) {
            entity.setMediaStatus("0");
        }
        List<String> labelList = Optional.ofNullable(dto.getLabelList()).orElse(new ArrayList<>());
        if (CollUtil.isNotEmpty(labelList)) {
            entity.setLabel(labelList.stream().map(label -> label.trim()).collect(Collectors.joining(",")));
        }
        return this.updateById(entity);
    }

    @Override
    public Boolean removeCvdQuestionAnswerBatchByIds(List<Long> ids) {
        Assert.notEmpty(ids, "ID不可为空！");
        List<CvdQuestionAnswerEntity> delList = this.list(Wrappers.<CvdQuestionAnswerEntity>lambdaQuery()
                .in(CvdQuestionAnswerEntity::getId, ids));
        for (CvdQuestionAnswerEntity entity : delList) {
            if (SYS_INNER_TYPE.equals(entity.getType())) {
                throw new RuntimeException("无法删除系统内置类型！");
            }
        }
        return this.removeBatchByIds(ids);
    }

    @Override
    public R importData(boolean cover, List<CvdQuestionAnswerExcelVO> excelVOList, BindingResult bindingResult) {
        // 通用校验获取失败的数据
        List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
        List<String> typeList = new ArrayList<>();
        SysDict sysDict = sysDictService.getOne(Wrappers.<SysDict>lambdaQuery()
                .eq(SysDict::getDictType, "cvd_question_type"));
        if (sysDict != null) {
            List<SysDictItem> sysDictItemList = sysDictItemService.list(Wrappers.<SysDictItem>lambdaQuery()
                    .eq(SysDictItem::getDictId, sysDict.getId()));
            typeList = sysDictItemList.stream().map(SysDictItem::getItemValue).collect(Collectors.toList());
        }
        // 执行数据插入操作 组装 UserDto
        for (CvdQuestionAnswerExcelVO excel : excelVOList) {

            Set<String> errorMsg = new HashSet<>();
            // 校验分类是否存在
            boolean existType = typeList.stream().anyMatch(x -> excel.getType().equals(x));

            if (!existType) {
                errorMsg.add("不存在" + excel.getType() + "分类");
            }
            if (CollUtil.isNotEmpty(errorMsg)) {
                // 数据不合法情况
                errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
            }
        }
        if (CollUtil.isNotEmpty(errorMessageList)) {
            return R.failed(errorMessageList);
        }else {
            if (cover) {//删除旧数据
                this.remove(Wrappers.<CvdQuestionAnswerEntity>lambdaQuery()
                        .ne(CvdQuestionAnswerEntity::getType, SYS_INNER_TYPE));
            }
            for(CvdQuestionAnswerExcelVO excel : excelVOList){
                insertExcelData(excel);
            }
        }
        return R.ok();
    }

    /**
     * 插入excel 数据
     */
    private void insertExcelData(CvdQuestionAnswerExcelVO excel) {
        CvdQuestionAnswerEntity entity = new CvdQuestionAnswerEntity();
        BeanUtils.copyProperties(excel, entity);
        this.save(entity);
    }
}